(function($){
	function hideMenu() {
		$(".menuContent").fadeOut("fast").find(".resize").mouseup();
		$("body").unbind("mousedown", onBodyDown);
	}
	var show = function(e){
		var options = $(e).ztreebox("options");
		if(options.expandAll==true){
			$.fn.zTree.getZTreeObj(options.tree).expandAll(true);
			if(options.disParents){
				$(e).ztreebox("disParents");
			}
		}
		if(options.isdisable!=true){
			var ee = $(e).next();

			var offset = ee.offset();

			if((document.body.offsetHeight-offset.top)<=(parseInt(options.cheight.split('px')[0])+50)){
				$("#"+options.div).css({"height":"auto",position:"absolute","border":"1px solid #ddd","border-bottom":"none",top:(offset.top-parseInt(options.cheight.split('px')[0])) + "px",left:offset.left+"px"}).show();
				$("#"+options.div).children("div").css({"height":options.cheight,"border-bottom":"1px solid #ddd"})
			}else{
				$("#"+options.div).css({"height":"auto",position:"absolute","border":"1px solid #ddd","border-top":"none",top:offset.top + ee.outerHeight() + "px",left:offset.left+"px"}).slideDown("fast");
				$("#"+options.div).children("div").css({"height":"auto"});
			}
			if($("#"+options.div).outerWidth()<$(e).next().width()){
				$("#"+options.div).width(ee.width());
			}
			$("body").bind("mousedown scroll drag", onBodyDown);
			$("#"+options.div).bind("mousedown",function(e){
				e.stopPropagation();
			});

			$("*").bind("scroll drag", onBodyDown);
			//终止 当前元素事件
			$("#"+options.div).find("*").unbind("scroll").bind("scroll",function(e){
				e.stopPropagation();
			});
			$(e).next().bind("mousedown",function(e){
				e.stopPropagation();
			});
		}
	}
	function onBodyDown(event) {
		if (!(event.target.id == "menuBtn" || event.target.id == "menuContent" || $(event.target).parents("#menuContent").length>0)) {
			hideMenu();
		}
	}
	$(window).resize(function(){
		hideMenu();
	});
	$.ztreeparser = function(jq){
		var opt = jq.attr("data-options");
		if(!opt) opt = "";
		var _d = new Function("return {"+opt+"}");
		return _d();
	}
	$.fn.ztreebox = function(){
		if(typeof arguments[0]=="string"){
			var args = Array.prototype.slice.call(arguments,1);
			args.unshift(this);
			if($.fn.ztreebox.methods[arguments[0]]){
				return $.fn.ztreebox.methods[arguments[0]].apply(this, args);
			}else if(arguments[0] == 'selfDefin'){
				var n = arguments[1];
				var c = $.fn.ztreebox.config[arguments[0]];
				c.url = c.url+n.queryId;
				$.fn.ztreebox.config[arguments[0]].ztreeopt.callback.beforeClick = function(treeId, treeNode, clickFlag){
					if(!treeNode.isparent){
						$("#"+n.name).ztreebox('setValue',treeNode.name);
						$("#"+n.id).val(treeNode.id);
						$(".menuContent").hide();
					}
					return false;
				}
				arguments[0] = c;
			} else {
				arguments[0] = $.extend(true,$.fn.ztreebox.config[arguments[0]],arguments[1]);
			}

		}

		var end = $.extend(true,{},$.fn.textbox.defaults,$.fn.ztreebox.defaults,$.ztreeparser(this),arguments[0]);

		//终止鼠标点击事件 导致切换value
		var timer = 0,jq = this;
		end.inputEvents.keydown=function(){
			if(timer){
				clearTimeout(timer);
			}
			timer = setTimeout(function(){
				if($.trim(jq.textbox("getText"))==""){
					jq.ztreebox("clear");
				}
			},200);
		};
		end.inputEvents.blur=function(){};

		end.tree = "tree"+Math.ceil(Math.random()*1000000);
		end.div = "menuContent"+Math.ceil(Math.random()*1000000);
		end.value = this.val()||end.value;

		if(end.cheight.toString().indexOf("px")==-1){
			if(end.cheight.toString().indexOf("%")==-1){
				end.cheight = end.cheight +"px";
			}
		}
		var div = $('<div id="'+end.div+'" class="menuContent" style="background:#FFF;display:none;z-index: 9999;"><div class="panel-body panel-body-noheader test-1" style="max-height:'+end.cheight+';overflow-y: auto;"> <ul id="'+end.tree+'" class="ztree view"></ul></div></div>').appendTo($('body'));

		var resize = $('<div class="resize" style="padding:5px;position: absolute; bottom: 0; right: 0; cursor: nwse-resize; ">&nbsp;</div>').insertAfter(div.find("ul"));

		resize.on("mousedown",function(e){
			var width = $(this).closest(".menuContent").width();
			var height = $(this).closest(".menuContent").height();
			$.data(this,"dragopt",{enable:true,width:width,height:width,clientX:e.clientX,clientY:e.clientY});
		});
		var moumov = function(e){
			if($.data(this).dragopt&&$.data(this).dragopt.enable){
				var height = $.data(this).dragopt.height + (e.clientY-$.data(this).dragopt.clientY);
				var width = $.data(this).dragopt.width + (e.clientX-$.data(this).dragopt.clientX);
				resize.off("mousemove");
				$(this).parent().css("max-height",height).closest('.menuContent').css({"width":width,"height":height});
				resize.on("mousemove",moumov);
				clearTimeout($.data(this).dragopt.timer);
				$.data(this).dragopt.timer = setTimeout(function(){
					resize.mouseup();
				},200);
			}
		}
		resize.on("mousemove",moumov);

		resize.on("mouseup",function(e){
			if($.data(this,"dragopt"))
				$.data(this,"dragopt",{});
		});

		this.attr("ztreeboxname",end.name);

		if(end.searchable==false){
			end.icons.shift();
		}

		this.textbox(end);
		$.data(this[0],"ztreebox",{options:end});
		load(jq,end);

		if(end.data){
			loadData(jq,end);
		}
	}
	var loadData = function(jq,end){
		var val = jq.textbox("getValue");

		var node = val.split(","),data;
		if(end.data){
			data = end.ztreeopt.async.dataFilter(null,null,end.data,node);
		}
		var tree = $.fn.zTree.init($("#"+end.tree),$.extend(true,{textbox:jq},end.ztreeopt),data);

		$.data($("#"+end.tree)[0],"textbox",jq);

		jq.ztreebox("setValue",node);
		jq.ztreebox("disableNode",end.disable,true,true);

		end.onLoad.call(jq,tree);
	}
	var load = function(jq,end){
		if(end.url&&$.trim(end.url)!=''){
			$.ajax({
				url:end.url,
				data:end.param,
				dataType:"json",
				success:function(data){
					end.data = data;
					loadData(jq,end);
				}
			});
		}else{
			loadData(jq,end);
		}
	}
	$.fn.ztreebox.methods = {
			options:function(jq){
				if(jq.length == 0){
					return null;
				} else {
					return $.data(jq[0],"ztreebox").options;
				}
			},
			/**
			 * jq 当前节点对象   nodes 需要禁用的节点或节点数组或正则匹配
			 * disable 禁用属性   true Or false  true 禁用  false 启用节点选中功能，
			 * applyChild   是否应用到子节点   true 子节点也被禁用   false 不影响子节点
			 * */
			disableNode:function(jq,nodes,disable,applychild){
				var options = jq.ztreebox("options");
				var treeobj = $.fn.zTree.getZTreeObj(options.tree);
				var nodes = treeobj.getNodesByParam(options.ztreeopt.data.simpleData.idKey,nodes,null);
				if(nodes&&nodes.length>0){
					for(var nodeindex=(nodes.length-1);nodeindex>=0;nodeindex--){
						if(disable==false){
							nodes[nodeindex].chkDisabled = false;
						}else{
							nodes[nodeindex].chkDisabled = true;
						}
						if(applychild){
							var grepNode = function(node){
								if(node.children){
									for(var i=0;i<node.children.length;i++){
										if(grepNode(node.children[i])){
											break;
										}
									}
								}
								if(disable==false){
									node.chkDisabled = false;
								}else{
									node.chkDisabled = true;
								}
								treeobj.updateNode(node);
							}
							grepNode(nodes[nodeindex]);
							treeobj.updateNode(nodes[nodeindex]);
						}
					}
				}

			},
			setValue:function(jq,node){
				var options = jq.ztreebox("options");
				var treeobj = $.fn.zTree.getZTreeObj(options.tree);

				var nodes = treeobj.getNodesByParam(options.ztreeopt.data.simpleData.idKey,node,null);

				if(nodes&&nodes.length>0){
					var names=[],vals=[];
					$.each(nodes,function(i,item){
						names.push(item[options.ztreeopt.data.simpleData.nameKey].replace(/(.*?)<font(.*?)>(.*?)<\/font>(.*?)/,"$1$3$4"));
						vals.push(item[options.ztreeopt.data.simpleData.idKey]);
						treeobj.checkNode(item,true,false);
					});
					jq.textbox("setValue",names.toString());
					jq.next().find("input[type='hidden']").val(vals.toString());
					$.data(jq[0],"ztreebox").options.value=vals.toString();
				}else{
					treeobj.checkAllNodes(false);
					jq.textbox("setValue",node);
					$.data(jq[0],"ztreebox").options.value = node;
				}
			},
			clear:function(jq){
				return jq.each(function(){
					$(this).ztreebox("showNodes",true);
					$(this).textbox("setValue","");
					$(this).next().find("input[type='hidden']").val("");
					delete $.data(this,"ztreebox").options.value;
				});
			},
			showNodes:function(jq,nodes,clear){
				var treeObj = $(this).ztreebox("ztree");
				if(typeof nodes == "boolean"){ clear = nodes;nodes = [];};
				if(nodes.length==0){
					if(clear){
						nodes = treeObj.getNodesByFilter(function(node){
							if(node.checked) { treeObj.checkNode(node,false); }
							return node.isHidden;
						});
					} else
						nodes = treeObj.getNodesByFilter(function(node){
							return node.isHidden;
						});
				}
				treeObj.showNodes(nodes);
			},
			hideNodes:function(jq,nodes){
				return jq.each(function(){
					var treeObj = $(this).ztreebox("ztree");
					var grepNode = function(node){
						if(node.children){
							for(var i=0;i<node.children.length;i++){
								if(!grepNode(node.children[i]).isHidden){
									node.isHidden = false;
									break;
								}
							}
						}
						return node;
					}
					var node ,ns=[];
					for(var ni = 0;ni<nodes.length;ni++){
						node = grepNode(nodes[ni]);
						if(node.isHidden) ns.push(node);
					}

					treeObj.hideNodes(ns);
				});
			},
			ztree:function(jq){
				return $.fn.zTree.getZTreeObj($.data(jq[0],"ztreebox").options.tree);
			},
			reload:function(jq,url,param){
				if(param==undefined) param = {};
				var opt = $.extend(true,$.data(jq[0],"ztreebox").options,{url:url});
				opt.param = param;
				load(jq,opt);
			},
			readonly:function(jq,val){
				if(val==false){
					var opt = $.data(jq[0],"ztreebox");
					opt.options.isdisable=false;
					$.data(jq[0],"ztreebox",opt);
				}else{
					var opt = $.data(jq[0],"ztreebox");
					opt.options.isdisable=true;
					$.data(jq[0],"ztreebox",opt);
				}
			},
			search:function(jq,val){
				return jq.each(function(){
					if(!val) val = $(this).textbox("getText");
					if(!val||$.trim(val)==""){
						$(this).ztreebox("showNodes",true);
						return;
					} else
						$(this).ztreebox("showNodes",false);

					var treeObj = $(this).ztreebox("ztree");
					var opt = $(this).ztreebox("options");

					//获取需要隐藏的节点
					var nodes = treeObj.getNodesByFilter(function(node){
						node.isHidden = true;
						var reg = new RegExp(/(.*?)<font(.*?)>(.*?)<\/font>(.*?)/ig);
						node.name = node.name?node.name.replace(reg,"$1$3$4"):"";
						reg = new RegExp(eval("/(.*?)"+val+"(.*?)/ig"));
						if(node.checked==true||node[opt.ztreeopt.data.simpleData.nameKey].indexOf(val)!=-1){
							node.isHidden = false;
							node.name = node.name.replace(reg,"$1<font style='"+opt.ztreeopt.view.heightLight+"'>"+val+"</font>$2");
						}
						treeObj.updateNode(node);
						return node.isHidden;
					});
					$(this).ztreebox("hideNodes",nodes);
					treeObj.expandAll(true);
				})
			},
			disParents:function(jq){
				var options = jq.ztreebox("options");
				var treeobj = $.fn.zTree.getZTreeObj(options.tree);
				var nodes= treeobj.getNodes();

				var grepNode = function(node_){

					if(node_.children){
						for(var i=0;i<node_.children.length;i++){
							if(node_.children[i].children){
								grepNode(node_.children[i]);
							}
						}
					}
					if(node_.isparent){
						$("#"+node_.tId+"_span").css("background-color", "#e5e5e5");
					}
				}
				$.each(nodes,(function(i,node){
					grepNode(node);
				}))
			}
	}
	//TODO 需要增加查询功能
	$.fn.ztreebox.defaults = {
			url:"", //获取树的数据地址
			cheight:200,
			onLoad:function(){},//控件加载完成后执行的函数
			readonly:false, //只读属性
			textbox:undefined, 
			ztreebox_f:"ztreebox_f",
			searchable:false,
			clearicon:false,
			expandAll:false,
			icons:[{disable:false,iconCls:"icon-search2",handler:function(){
				$(this).closest(".textbox").prev().ztreebox("search");
			}},//查询 icon
			{disable:false,iconCls:"combo-arrow",handler:function(){
			}}],//下拉选择数据icon
			onClickIcon:function(index){ //建议不要重写
				if(index==0){
					//$(this).ztreebox("search");
					show(this);
				} else if(index==1){
					if($("#"+$(this).ztreebox("options").div).is(":hidden")){
						show(this);
					}else{
						hideMenu();
					}
				}
			},
			onClick:function(){
				show(this);
			},
			param:{},//请求树形数据需要提交的参数  json格式
			ztreeopt: {//ztree配置文件   参考API
				view: { 
					dblClickExpand: false,
					nameIsHTML: true,
					heightLight:"color:#F00"
				},
				check: {
					enable: true,
					chkStyle: "radio",
					radioType:"all"
				},
				data: { simpleData: { enable: true,idKey: "id",nameKey:"name",pIdKey: "pId" } },
				callback:{
					onCheck:function(event, treeId, treeNode){
						var jq = $.data($("#"+treeId)[0],"textbox");
						var treeobj = this.getZTreeObj(treeId);

						var nodes = treeobj.getCheckedNodes(true);
						jq.ztreebox("setValue",(function(nodes){
							for(var i=0;i<nodes.length;i++){
								nodes[i] = nodes[i][treeobj.setting.data.simpleData.idKey];
							}
							return nodes;
						})(nodes));
						treeobj.setting.callback.afterCheck.call(treeobj,nodes,treeobj.getCheckedNodes(true));
					},
					afterCheck:function(treeObj,treeNode,nodes){  },
					onClick:function(event, treeId, treeNode){
						if(treeNode.checked){
							$.fn.zTree.getZTreeObj(treeId).checkNode(treeNode, false, true);
						} else {
							$.fn.zTree.getZTreeObj(treeId).checkNode(treeNode, true, true);
						}
						var jq = $.data($("#"+treeId)[0],"textbox");
						var treeobj = this.getZTreeObj(treeId);

						var nodes = treeobj.getCheckedNodes(true);
						jq.ztreebox("setValue",(function(nodes){
							for(var i=0;i<nodes.length;i++){
								nodes[i] = nodes[i][treeobj.setting.data.simpleData.idKey];
							}
							return nodes;
						})(nodes));
						treeobj.setting.callback.afterCheck.call(treeobj,nodes,treeobj.getCheckedNodes(true));
					}
				},
				async:{
					enable:true,
					dataFilter:function(a,b,data){
						if(a){
							var grepParent = function(b,upfun){ if(b){ upfun(b); }else{ return; } return grepParent(b.getParentNode(),upfun); }
							var opt = this.getZTreeObj(a).setting;
							$.each(data.data,function(i,item){
								if(!item.halfCheck) delete item.halfCheck;
								if(item[opt.data.simpleData.idKey] == opt.textbox.textbox("getValue")){
									item.checked = true;
									grepParent(b,function(item){ delete item.halfCheck; });
									delete item.halfCheck;
								}
							})
						}
						return data.data;
					}
				}
			}
	}
	$.fn.ztreebox.config = {
			role:{
				edit:true,
				editable:true,
				searchable:true,
				url:BASEPATH+"/base/authoriza/role/getTreeall.htm",
				ztreeopt:{ check:{ radioType:"all" } }
			},
			dept:{
				edit:true,
				editable:true,
				searchable:true,
				url:BASEPATH+"/base/authoriza/dept/getTreeall.htm",
				ztreeopt:{ 
					check:{ 
						chkStyle: "checkbox", 
						chkboxType: { "Y": "", "N": "" }
					},
					callback:{
						beforeCheck:function(treeId, treeNode) {
							if(treeNode.checked)
								return true;
							else {
								var treeobj = this.getZTreeObj(treeId);
								treeobj.setting.check.chkboxType={ "Y": "ps", "N": "ps" }
								treeobj.checkNode(treeNode,false,true,false);
								treeobj.setting.check.chkboxType={ "Y": "", "N": "" }
								return true;
							}
						}
					} 
				}
			},
			selfDefin:{
				url:BASEPATH+"/base/authoriza/conmonData/queryDataNoCache.htm?queryId=",
				check:"radio",
				expandAll:true,
				disParents:true,
				ztreeopt:{
					data:{
						simpleData:{
							enable: true,
							idKey: "id",
							pIdKey: "pid",
							rootPId: 0
						}
					},
					view:{
						showIcon: false,
						showLine: false
					},
					check:{
						enable:false 
					},
					callback: {
						onClick: function(event, treeId, data) {},
						afterCheck: function(treeobj,data){},
						beforeCheck:function(treeId, treeNode){
							if(treeNode.isparent){									
								return false;
							}
						},
						beforeClick:function(treeId, treeNode, clickFlag){}
					}
				}
			}
	}
})($)
